WebSocket instead of HTTP-endpoint
Most modern web applications use WebSockets, when real-time data from servers need to be pushed out to the web applications, within a browser.
The implementation of the BACnet/WS in the DINGO-Stack, contains a HTTP-endpoint, that will proxy incoming HTTP-requests over on a open WebSocket-connection.
To use this option, the user has to follow these steps:
- Create a subscription as described earlier, but modify the callback:
"callback": "http://192.168.1.110/bacnetws/cov-http-to-ws-proxy"
where the IP address in the example is the address of the DINGO device that is hosting the BACnet web-services. - Get the identifier (e.g. 1) provided for the created subscription, by parsing the HTTP-reply.
- Use the identifier (e.g. 1) and create a WebSocket connection to ws://192.168.1.110/bacnetws/cov-http-to-ws-proxy/1?alt=json where the IP address in the example is the address of the DINGO device that is hosting the BACnet web-services.
Study the following JavaScript functions to see how the subscription and WebSocket connection is made .
function CreateSubscribtion(device,object) {
// device could for example be: 1000
// object could for example be: analog-input,18
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
// SUBSCRIPTION CREATED
var headerString = xmlHttp.getResponseHeader("Location");
if (headerString != null) {
var urlParts = headerString.split("/");
subscribtionID = urlParts[urlParts.length - 1];
WebSocketSubscribe(urlParts[urlParts.length - 1]);
}
}
}
// CREATE BACnet/WS SUBSCRIPTION
var host = "192.168.1.110";
xmlHttp.open("POST", "http://" + host + "/bacnetws/.subs?alt=json", true); // true for asynchronous
var subscription = {
label: "My subscription",
callback: "http://" + host + "/bacnetws/cov-http-to-ws-proxy",
lifetime: "120",
covs: {
1: {
path: "/.bacnet/.local/" + device + "/" + object,
increment: "1"
}
}
};
xmlHttp.send(JSON.stringify(subscription));
}
function WebSocketSubscribe(id) {
var host = "192.168.1.110";
var wslocation = "ws://" + host + "/bacnetws/cov-http-to-ws-proxy/" + id + "?alt=json";
if ("WebSocket" in window) {
// CONNECTING TO WEBSOCKET
ws = new WebSocket(wslocation);
ws.onopen = function (event) {
// CONNECTED
};
ws.onmessage = function (evt) {
// RECIEVED DATA
var msg = evt.data.toString();
// Chrome and Firefox could not parse JSON to object,
// not until we replace control characters out of the string.
msg = msg.replace(/[\x00-\x1F\x7F-\x9F]/g, "");
try {
var obj = JSON.parse(msg);
alert(obj["1"].$value);
}
catch (e) {
alert(msg);
}
};
ws.onclose = function () {
// CONNECTION CLOSED
};
ws.onerror = function (error) {
alert("ERROR: " + error.data);
};
}
else {
alert("This browser does not support WebSockets.");
}
}
A web application (testclient.htm) exists on the file system, that uses WebSockets and can be studied furthered.